// 0. 装包 yarn add vuex@3.4.0
// 1. 引入 Vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 2. 安装插件
// Vue.use(VueRouter)
Vue.use(Vuex)

// 3. 创建 Store 对象
// new VueRouter()
const store = new Vuex.Store({
  // 核心成员1: state
  // 作用: 存储共享数据的
  // 相当于在组件内的 data, 区别是 data 只能给当前组件使用, 而 state 可以给所有组件使用
  // 组件内的访问方式:
  // 1. 直接访问: this.$store.state.count
  // 2. 辅助函数:
  //   a. 按需导入辅助函数
  //   b. 使用辅助函数在 computed 处展开
  state: {
    count: 101,
    name: '马经理',
    list: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
  },
  // 核心成员2: mutations
  // 作用: 修改 state 的数据
  // 原则: 不允许在任何情况下直接操作 state 的数据, 如果需要修改必须通过 mutations 来修改
  // mutation 就是一个函数而已
  mutations: {
    // mutation 函数都有参数
    // 参数1: 永远都是 state
    incremCount(state) {
      // 专门用来操作 state 数据的函数
      // 通过它操作 state 会留下记录, 方便将来调试
      state.count++
    },
    // 带参数的 mutation
    // 需要接受外部的参数
    // 给我传什么, 我就改成什么
    // 参数1: state
    // 参数2: 传入的数据
    changeCount(state, num) {
      state.count = num
    },
    // 辅助函数 mapMutations 的用法:
    // 1. 按需导入辅助函数
    // 2. 使用辅助函数, 在 methods 处展开
    // 辅助函数一般在组件内需要多次调用方法时, 才会使用, 否则还不如直接用 this.$store.commit()

    // 在 mutations 中不能进行异步修改 state
    // asyncIncrem(state) {
    //   // 如果在 mutations 中做异步操作, 会导致调试工具无法正确的监视到数据变化
    //   // 它会在这个函数执行的时候立即监视到操作, 而此时数据没变, 就会出现异常的情况
    //   setTimeout(() => {
    //     state.count++
    //   }, 1000)
    // }
  },
  // 核心成员3: actions
  actions: {
    // 在 actions 中不能直接操作 state
    // 而是要交给 mutations 操作 state
    // 参数1: context 是 Store 的对象 (上下文对象), 可以调用 commit 来触发 mutations
    asyncIncrem(context) {
      setTimeout(() => {
        context.commit('incremCount')
      }, 1000)
    },
    // actions 同样也可以接收参数
    // 参数2: 组件传递过来的参数
    // 同样也有辅助函数
    asyncChangeCount(context, num) {
      setTimeout(() => {
        context.commit('changeCount', num)
      }, 1000)
    }
  },
  getters:{
    //相当于Vuex中的计算属性
    //这个计算属性只能是函数，只能提供数据访问，不能修改数据
    //参数1:state
    // 辅助函数,用法同上 
    arr(state) {
      return state.list.filter(item=> item >5)
    }
  }
  // 辅助函数大总结:
  // 一共学了四个辅助函数: mapState mapMutations mapActions mapGetters
  // 函数: mapMutations mapActions, 应该在 methods 中调用并展开
  // 数据: mapState mapGetters, 应该在 computed 中调用并展开
  // 建议: 一般情况下我只习惯用两个, mapState 和 mapGetters
})

// 4. 导出一个 store 对象
export default store